home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 10
/
AACD 10.iso
/
AACD
/
Magazine
/
Online
/
OpenURL
/
Developer
/
Source
/
OpenURL.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-09-26
|
7KB
|
261 lines
/*
* OpenURL -- A Workbech/CLI frontend for "openurl.library".
*
* Written by Thomas Aglassinger <agi@sbox.tu-graz.ac.at>
* Placed in the public domain.
*
* Based on material provided by Troels Walsted Hansen <troels@thule.no>
*/
#include <exec/memory.h>
#include <dos/dos.h>
#include <libraries/openurl.h>
#include <intuition/intuition.h>
#include <string.h>
#include "SmartReadArgs.h"
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/openurl.h>
static const char *version = "\0$VER: OpenURL 1.1 " __AMIGADATE__;
#define TEMPLATE "URL/A,NOSHOW/S,NOFRONT/S,NEWWIN/S,NOLAUNCH/S,FILE/S"
enum
{
A_URL, A_NOSHOW, A_NOFRONT, A_NEWWIN, A_NOLAUNCH, A_FILE, A_MAX
};
/* Maximum length an URL can get according to w3c. Currently, CLI
* imposes even a smaller limit of 512. */
#define MAXIMUM_URL_LENGTH 1024
struct Library *OpenURLBase;
#define OPENURL_VERSION 1 /* Minimum version of openurl.library */
#define OPENURL_VERSION_STR "1" /* Used by error message */
#define MAXIMUM_ERROR_LENGTH 120 /* Size of buffer for error messages */
/* Some shit necessary because C standard libraries suck */
ULONG ulong_max(ULONG a, ULONG b)
{
if (a > b)
{
return a;
}
else
{
return b;
}
}
/* Main function
*
* Note that the startup code of SAS/c sets argc=0 when started from
* workbench. This fact is used to auto-enable FILE in such a case.
*/
int main(int argc, char *argv[])
{
int return_code = RETURN_FAIL;
/* Error code from dos.library's IoErr() */
LONG error_code = 0;
/* Description of the action failed. If error_code is 0, only this
* text is displayed. Otherwise, also the DOS error message is
* appended. */
STRPTR error_cause = NULL;
/* Workbench startup message or NULL if started from CLI */
struct WBStartup *wb_startup = NULL;
/* Buffer for error messages. This is not allocated dynamically because
* then it might not exist in case of no memory. */
UBYTE error_buffer[MAXIMUM_ERROR_LENGTH] =
{NULL};
if ((OpenURLBase = OpenLibrary("openurl.library", OPENURL_VERSION)))
{
struct SmartArgs smart_args =
{NULL};
LONG args[A_MAX] =
{0};
/* The URL passed to URL_Open() */
STRPTR real_url = NULL;
/* The fully qualified filename, if any */
STRPTR filename = NULL;
/* Prepare argument parsing */
smart_args.sa_Template = TEMPLATE;
smart_args.sa_Parameter = args;
smart_args.sa_FileParameter = A_URL;
smart_args.sa_Window = "CON:////OpenURL/AUTO/CLOSE/WAIT";
return_code = RETURN_ERROR;
/* Auto-enable FILE switch when started from WB */
if (argc == 0)
{
wb_startup = (struct WBStartup *) argv;
args[A_FILE] = 1;
}
/* Parse arguments, either from Workbench or CLI */
error_code = SmartReadArgs(wb_startup, &smart_args);
/* Allocate string buffers. This reduces stack usage and also
* makes the string buffers being checked by Mungwall.
*
* Yes, this wastes some memory if FILE is not set, but makes the
* error handling easier.
*
* Yes, we could use a 2K buffer with filename = real_url + 1024 to
* use only one allocation. This however would reduce the possibilty
* for out-of-bounds checks for the end of one/beginning of the
* other string. */
if (error_code == 0)
{
/* Allocate string buffers */
real_url = AllocVec(MAXIMUM_URL_LENGTH, MEMF_ANY);
filename = AllocVec(MAXIMUM_URL_LENGTH, MEMF_ANY);
if ((real_url == NULL) || (filename == NULL))
{
/* Not enough memory */
SetIoErr(ERROR_NO_FREE_STORE);
error_code = IoErr();
}
}
if (error_code == 0)
{
if (args[A_FILE])
{
/* Expand the filename to a fully qualified URL */
BPTR lock = Lock((STRPTR) args[A_URL], ACCESS_READ);
if (lock != NULL)
{
if (NameFromLock(lock, filename, MAXIMUM_URL_LENGTH))
{
strcpy(real_url, "file://localhost/");
strncat(real_url, filename, MAXIMUM_URL_LENGTH);
}
else
{
error_cause = "Error obtaining full filename";
error_code = IoErr();
}
UnLock(lock);
}
else
{
error_cause = "Error opening input file";
error_code = IoErr();
}
}
else
{
/* Simply use the URL passed in arguments, assuming it is
* an already fully qualified URL of any protocol. Possible
* errors are now treated by the browser. */
strncpy(real_url, (STRPTR) args[A_URL], MAXIMUM_URL_LENGTH);
}
/* Make sure that the URL gets a trailing zero (just in case
* someone passed a too long one). */
real_url[MAXIMUM_URL_LENGTH - 1] = '\0';
if (error_code == 0)
{
/* Really show it */
if (URL_Open(real_url,
URL_Launch, !args[A_NOLAUNCH],
URL_Show, !args[A_NOSHOW],
URL_BringToFront, !args[A_NOFRONT],
URL_NewWindow, args[A_NEWWIN],
TAG_DONE))
{
return_code = RETURN_OK;
}
else
{
error_code = 0;
if (args[A_NOLAUNCH])
{
error_cause = "Could not find browser port";
}
else
{
error_cause = "Could not launch browser";
}
}
}
}
else
{
error_cause = "Error in arguments";
}
/* Free extended read args (even in case of error) */
SmartFreeArgs(&smart_args);
/* Release all other resources */
if (filename != NULL)
{
FreeVec(filename);
}
if (real_url != NULL)
{
FreeVec(real_url);
}
CloseLibrary(OpenURLBase);
}
else
{
error_cause =
"Could not find \"openurl.library\", "
"version " OPENURL_VERSION_STR;
}
/* Create error message in error_buffer (if any) */
if (error_code != 0)
{
Fault(error_code, error_cause, error_buffer, MAXIMUM_ERROR_LENGTH);
}
else if (error_cause != NULL)
{
strncpy(error_buffer, error_cause, MAXIMUM_ERROR_LENGTH - 1);
}
/* Display error message in CLI or Requester (if any) */
if (error_buffer[0] != '\0')
{
if (wb_startup != NULL)
{
struct EasyStruct error_requester =
{
sizeof(struct EasyStruct),
0,
"OpenURL Error",
"%s",
"Cancel"
};
EasyRequest(NULL, &error_requester, NULL, error_buffer);
}
else
{
FPuts(Output(), error_buffer);
FPuts(Output(), "\n");
}
}
return (return_code);
}